package com.faya.green.utils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * 用户 ：LX
 * 创建时间： 2018/7/12. 9:32
 * 地点：广州
 * 目的: 日期工具类
 * 结果：
 */
public class DateUtils {

    /**
     * 仅仅将每一位数字直接转换成中文字
     */
    private final static int TRANSLATE_NUMBER_ONEBYONE = 1;

    /**
     * 转换数字成中文数字形式
     */
    private final static int TRANSLATE_NUMBER_TO_NUMERICTPYE = 0;

    /**
     * 计算两个日期相差天数。
     * 用第一个日期减去第二个。如果前一个日期小于后一个日期，则返回负数
     * @param one 第一个日期数，作为基准
     * @param two 第二个日期数，作为比较
     * @return 两个日期相差天数
     */
    public static long diffDays(Date one, Date two){
        return (one.getTime() - two.getTime()) / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取当前日期是星期几<br>
     * @param dt
     * @return 当前日期是星期几
     */
    public static String getWeekOfDate(Date dt) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return weekDays[w];
    }

    /**
     * 计算两个日期相差月份数
     * 如果前一个日期小于后一个日期，则返回负数
     * @param one 第一个日期数，作为基准
     * @param two 第二个日期数，作为比较
     * @return 两个日期相差月份数
     */
    public static int diffMonths(Date one, Date two) {
        Calendar calendar = Calendar.getInstance();
        //得到第一个日期的年分和月份数
        calendar.setTime(one);
        int yearOne = calendar.get(Calendar.YEAR);
        int monthOne = calendar.get(Calendar.MONDAY);
        //得到第二个日期的年份和月份
        calendar.setTime(two);
        int yearTwo = calendar.get(Calendar.YEAR);
        int monthTwo = calendar.get(Calendar.MONDAY);
        return (yearOne - yearTwo) * 12 + (monthOne - monthTwo);
    }



    /**
     * 根据日期格式将日期转换成字符串
     *
     * @param d      日期
     * @param format 日期格式
     * @return 符合格式的日期字符串
     */
    public static String dateToString(Date d, String format) {
        if (d == null) {
            return "";
        }
        if (format == null) {
            format = "yyyyMMdd";
        }
        String retString = null;
        String f = format.replace('Y', 'y');
        f = f.replace('m', 'M');
        f = f.replace('D', 'd');
        SimpleDateFormat df = new SimpleDateFormat(f);
        retString = df.format(d);
        return retString;
    }


    /**
     * 转换成中文的日期格式
     *
     * @param date
     * @return
     */
    public static String toChineseDateStyle(java.sql.Date date) {
        if (date == null) {
            return "";
        } else {
            return new SimpleDateFormat("yyyy年MM月dd日").format(date);
        }
    }

    public static String toChineseDateStyle(Date date) {
        if (date == null) {
            return "";
        } else {
            return new SimpleDateFormat("yyyy年MM月dd日").format(date);
        }
    }

    /**
     * 把阿拉伯数字字符串转换成对应的中文数字字符串
     *
     * @param s             要转换的字符串
     * @param translateType 转换的类型，1表示只是把每个阿拉伯数字转换成中文，
     *                      如“24”转换成“二四”。
     *                      2表示在转换的同时还要加上单位，如“24”转换成“二十四”
     * @return
     */
    public static String numberToChinese(String s, int translateType) {
        String name[] = {"○", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        String ffix[] = {"", "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千", "万"};
        int mods[] = {1, 10, 100, 1000, 10000};
        String ret = "";
        int len = s.length();

        if (translateType == TRANSLATE_NUMBER_ONEBYONE) {
            s = s + " ";
            for (int i = 0; i < len; i++) {
                String ch = s.substring(i, i + 1);
                int value = Integer.parseInt(ch);
                ret = ret + name[value];
            }
        }

        // function right between only 0~99999
        if (translateType == TRANSLATE_NUMBER_TO_NUMERICTPYE) {
            // format int string.
            int value = Integer.parseInt(s);
            String formatedString = new Integer(value).toString();
            len = formatedString.length();
            if (value == 0) {
                ret = name[0];
            } else {
                String zero = "";
                for (int i = 0; i < len; i++) {
                    int sign = Integer.parseInt(formatedString.substring(i, i + 1));
                    if (sign == 0) {
                        if (len - i == 9) {
                            ret = ret + "亿";
                        }
                        if (len - i == 5 && !"亿".equals(ret.substring(ret.length() - 1))) {
                            ret = ret + "万";
                        }
                        if ("".equals(zero)) {
                            zero = zero + name[0];
                        } else {
                            continue;
                        }
                    } else {
                        if ("".equals(zero)) {
                            ret = ret + name[sign] + ffix[len - i - 1];
                        } else {
                            ret = ret + zero + name[sign] + ffix[len - i - 1];
                            zero = "";
                        }
                    }
                }
                if ((value >= 10 && value < 20) || (value >= 10 * 10000 && value < 20 * 10000) || (value >= 10 * 100000000 && value < 20 * 100000000)) {
                    ret = ret.substring(1);
                }
            }
        }

        return ret;
    }

    /**
     * 把数据库日期格式的日期转换成中文的日期，
     * 如“2004-10-27”转换成“二○○四年十月二十七”
     *
     * @param d
     * @return
     */
    public static String dateToChineseFormatDate(Date d) {
        if (d == null) {
            return "";
        }

        SimpleDateFormat df = new SimpleDateFormat("yyyy");
        SimpleDateFormat df1 = new SimpleDateFormat("MM");
        SimpleDateFormat df2 = new SimpleDateFormat("dd");
        String ch = numberToChinese(df.format(d), TRANSLATE_NUMBER_ONEBYONE) + "年";
        ch = ch + numberToChinese(df1.format(d), TRANSLATE_NUMBER_TO_NUMERICTPYE) + "月";
        ch = ch + numberToChinese(df2.format(d), TRANSLATE_NUMBER_TO_NUMERICTPYE) + "日";
        return ch;
    }


    /**
     * 把数据库日期格式的日期转换成中文的日期，
     * 如“2004-10-27”转换成“二○○四年十月二十七”，注意参数checkAfterMax的使用
     *
     * @param date
     * @param checkAfterMax 是否检查超过系统定义最大日期，为true时则输出空字符串，
     *                      为false则输出转过的值
     * @return
     */
    public static String dateToChineseFormatDate(Date date, boolean checkAfterMax) {
        if (date == null) {
            return "";
        }
        if (checkAfterMax) {
            return "";
        }

        return dateToChineseFormatDate(date);
    }


    /**
     * 得到年份
     * @param birthDate
     * @return
     */
    public static int getAge(java.sql.Timestamp birthDate) {
        int age = 0;
        try {
            if (birthDate == null) {
                birthDate = new java.sql.Timestamp(System.currentTimeMillis());
            }
            int curYear = Calendar.getInstance().get(Calendar.YEAR);
            Calendar cal = Calendar.getInstance();
            cal.setTimeInMillis(birthDate.getTime());
            int birthYear = cal.get(Calendar.YEAR);
            age = curYear - birthYear;
        } catch (Exception ex) {
            ex.printStackTrace();
            return age;
        }
        return age;
    }


    /***
     * 日期月份减一个月
     * @param datetime 日期(2014-11)
     * @return 2014-10
     */
    public static String dateFormat(String datetime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Date date = null;
        try {
            date = sdf.parse(datetime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cl = Calendar.getInstance();
        cl.setTime(date);
        cl.add(Calendar.MONTH, -1);
        date = cl.getTime();
        return sdf.format(date);
    }

    /****
     * 传入具体日期 ，返回具体日期减一个月。
     * @param date 日期(2014-04-20)
     * @return 2014-03-20
     * @throws ParseException
     */
    public static String subMonth(String date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = sdf.parse(date);
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(dt);

        rightNow.add(Calendar.MONTH, -1);
        Date dt1 = rightNow.getTime();
        String reStr = sdf.format(dt1);

        return reStr;
    }

    /**
     * 获取月末最后一天
     * @param sDate 2014-11-24
     * @return 30
     */
    public static String getMonthMaxDay(String sDate) {
        SimpleDateFormat sdf_full = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        Date date = null;
        try {
            date = sdf_full.parse(sDate + "-01");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        cal.setTime(date);
        int last = cal.getActualMaximum(Calendar.DATE);
        return String.valueOf(last);
    }

    /**
     * 判断是否是月末
     * @param date
     * @return
     */
    public static boolean isMonthEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if (cal.get(Calendar.DATE) == cal.getActualMaximum(Calendar.DAY_OF_MONTH)) {
            return true;
        } else {
            return false;
        }
    }

    /***
     * 日期减一天、加一天
     * @param option 传入类型 pro：日期减一天，next：日期加一天
     * @param dateStr  2014-11-24
     * @return 减一天：2014-11-23或(加一天：2014-11-25)
     */
    public static String checkOption(String option, String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cl = Calendar.getInstance();
        Date date = null;

        try {
            date = (Date) sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        cl.setTime(date);
        if ("pre".equals(option)) {
            // 时间减一天
            cl.add(Calendar.DAY_OF_MONTH, -1);

        } else if ("next".equals(option)) {
            // 时间加一天
            cl.add(Calendar.DAY_OF_YEAR, 1);
        } else {
            // do nothing
        }
        date = cl.getTime();
        return sdf.format(date);
    }

    /***
     * 对日期加减
     * @param option 传入类型 pre：日期减N天，next：日期加N天
     * @param _date  2014-11-24 要加减的时间
     * @param day  要加减的天
     * @return 减一天：2014-11-23或(加一天：2014-11-25)
     */
    public static String addReduceOption(String option, String _date, int day) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cl = Calendar.getInstance();
        Date date = null;

        try {
            date = (Date) sdf.parse(_date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        cl.setTime(date);
        if ("pre".equals(option)) {
            cl.add(Calendar.DAY_OF_MONTH, -day);

        } else if ("next".equals(option)) {
            cl.add(Calendar.DAY_OF_YEAR, day);
        } else {
            // do nothing
        }
        date = cl.getTime();
        return sdf.format(date);
    }


    /***
     * 判断日期是否为当前月， 是当前月返回当月最小日期和当月目前最大日期以及传入日期上月的最大日和最小日
     * 不是当前月返回传入月份的最大日和最小日以及传入日期上月的最大日和最小日
     * @param date 日期 例如：2014-11
     * @return String[] 开始日期，结束日期，上月开始日期，上月结束日期
     * @throws ParseException
     */
    public static String[] getNow_Pre_Date(String date) throws ParseException {

        String[] str_date = new String[4];
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat sdf_full = new SimpleDateFormat("yyyy-MM-dd");
        String stMonth = sdf.format(now);
        String stdate = "";// 开始日期
        String endate = "";// 结束日期
        String preDate_start = "";// 上月开始日期
        String preDate_end = "";// 上月结束日期

        // 当前月
        if (date.equals(stMonth)) {
            stdate = stMonth + "-01"; // 2014-11-01
            endate = sdf_full.format(now);// 2014-11-24
            preDate_start = subMonth(stdate);// 2014-10-01
            preDate_end = subMonth(endate);// 2014-10-24
        } else {
            // 非当前月
            String monthMaxDay = getMonthMaxDay(date);
            stdate = date + "-01";// 2014-10-01
            endate = date + "-" + monthMaxDay;// 2014-10-31
            preDate_start = subMonth(stdate);// 2014-09-01
            preDate_end = subMonth(endate);// 2014-09-30
        }
        str_date[0] = stdate;
        str_date[1] = endate;
        str_date[2] = preDate_start;
        str_date[3] = preDate_end;

        return str_date;
    }

    /**
     * 获取当前年份
     */
    public static String getYear() {
        Calendar cd = Calendar.getInstance();
        return String.valueOf(cd.get(Calendar.YEAR));
    }

    /**
     * 获取当前月份
     * @return
     */
    public static String getMonth() {
        Calendar cd = Calendar.getInstance();
        return String.valueOf(cd.get(Calendar.MONTH) + 1);
    }

    /**
     * 将 类似  String str = "Wed Oct 04 00:00:00 CST 2000"; 这种格式的时间转换为  2000-10-04 00:00:00
     * @param str  Wed Oct 04 00:00:00 CST 2000  时间格式
     * @return
     */
    public static String webCSTTransformation(String str){
        SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
        Date date = null;
        try {
            date = (Date) sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        String formatStr2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
        return formatStr2;
    }


    /**
     * 获取当前的年月日
     * @return
     */
    public static String getDate(){
        String date = new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime());
//        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime());
        return date;
    }

    /**
     * 日期转换成字符串
     * @param date
     * @return str
     */
    public static String dateToStr(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String str = format.format(date);
        return str;
    }

    /**
     * 日期转换成字符串
     * @param date
     * @return str
     */
    public static String dateToStrYMD(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String str = format.format(date);
        return str;
    }

    /**
     * String --> java.sql.Timestamp the format is "yyyy-MM-dd HH:mm:ss.fffffffff",
     * the length of 'f' is less than 9 and it can omit.
     */
    public static Timestamp str2timestamp(String str){
        if(str ==null || str.trim().length() == 0){
            return null;
        }
        Timestamp timestamp = Timestamp.valueOf(str.trim());
        return timestamp;
    }

    /**
     *java.util.Date -- > java.sql.Date
     */
    public static java.sql.Date uDate2sDate(java.util.Date uDate){
        if(uDate == null){
            return null;
        }
        java.sql.Date sDate=new java.sql.Date(uDate.getTime());
        return sDate;
    }

    /**
     * java.util.Date --> java.sql.Timestamp
     */
    public static java.sql.Timestamp uDate2timestamp(java.util.Date uDate){
        if(uDate == null){
            return null;
        }
        Timestamp timestamp = new Timestamp(uDate.getTime());
        return timestamp;
    }

    /**
     * Date类型转换到Calendar类型
     * @param d
     * @return
     */
    public static Calendar Date2Calendar(Date d){
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c;
    }

    /**
     * Calendar类型转换到Date类型
     * @param c
     * @return
     */
    public static Date Calendar2Date(Calendar c){
        return c.getTime();
    }

    /**
     * java.sql.Date --> String, the format of str must be 'yyyy-MM-dd'.
     */
    public static String sDate2str(java.sql.Date sDate){
        if(sDate == null){
            return null;
        }
        String str = sDate.toString();
        return str;
    }

    /**
     * java.sql.Date --> long
     */
    public static long sDate2long(java.sql.Date sDate){
        if(sDate == null){
            return 0L;
        }
        long time = sDate.getTime();
        return time;
    }

    /**
     *java.sql.Timestamp --> java.util.Date
     */
    public static java.util.Date timestamp2uDate(Timestamp timestamp){
        if(timestamp == null){
            return null;
        }
        long milliseconds = timestamp.getTime();
        java.util.Date uDate = new java.util.Date(milliseconds);
        return uDate;
    }


    /**
     * long --> java.sql.Date
     */
    public static java.sql.Date long2sDate(long time){
        if(time == 0L){
            return null;
        }
        java.sql.Date sDate = new java.sql.Date(time);
        return sDate;
    }

    /**
     * long --> java.sql.Timestamp
     */
    public static Timestamp long2timestamp(long time){
        if(time == 0L){
            return null;
        }
        Timestamp timestamp = new Timestamp(time);
        return timestamp;
    }

    /**
     * 字符串转换成日期
     * @param str
     * @return date
     */
    public static Date strToDate(String str) {
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * date转换成 long类型
     * @param date 日期
     * @return long类型日期 （毫秒），如果想返回描述，long mseconds=date.getTime()/1000; ,除以1000
     */
    public static Long dateToLong(Date date){
        return date.getTime();
    }

    /**
     * 将long类型转化为Date
     * @param str
     * @return
     * @throws ParseException
     */
    public static Date LongToDare(long str) throws ParseException{
//        return new Date(str * 1000); //秒的
        return new Date(str);
    }

    /**
     * 将CST时间类型字符串进行格式化输出
     * @param str
     * @return
     * @throws ParseException
     */
    public static String cSTFormat(String str) throws ParseException{
        SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
        Date date = (Date) formatter.parse(str);
        SimpleDateFormat form = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = form.format(date);
        return dateString;
    }


}
